package ar.com.spsolutions.splibrary.user;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import ar.com.spsolutions.splibrary.book.Book;
import ar.com.spsolutions.splibrary.book.LoanBook;
import ar.com.spsolutions.splibrary.entity.Entity;
import ar.com.spsolutions.splibrary.user.role.UserRole;

public class User extends Entity {
	private static final long serialVersionUID = 1607126665947351082L;

	private static final int RENTAL_LIMIT = 3;

	private String name;

	private String email;

	private String password;

	private UserRole role;

	private Set<LoanBook> loans = new HashSet<LoanBook>();

	public void addLoan(final LoanBook loan) {
		this.getLoans().add(loan);
	}

	public boolean canRentAnotherBook() {
		return this.getLoans().size() < User.RENTAL_LIMIT;
	}

	public boolean isAdmin() {
		return this.getRole().isAdmin();
	}

	public boolean hasRentsDue() {
		final Iterator<LoanBook> iterator = this.getLoans().iterator();
		boolean hasDue = false;
		while (!hasDue && iterator.hasNext()) {
			final LoanBook rentBook = iterator.next();
			hasDue = rentBook.isDue();
		}
		return hasDue;
	}

	public Set<LoanBook> getLoansDue() {
		final Iterator<LoanBook> iterator = this.getLoans().iterator();
		final Set<LoanBook> dues = new HashSet<LoanBook>();
		while (iterator.hasNext()) {
			final LoanBook rentBook = iterator.next();
			if (rentBook.isDue()) {
				dues.add(rentBook);
			}
		}
		return dues;
	}

	public boolean hasTheBookRented(final Book book) {
		// transforma el hash de libros rentados en una lista de libros para que
		// puedan ser comparados por isbn

		final List<LoanBook> librosRentados = new ArrayList<LoanBook>();

		final Iterator<LoanBook> iterador = this.getLoans().iterator();
		while (iterador.hasNext()) {
			librosRentados.add(iterador.next());
		}

		boolean resultado = false;
		for (int i = 0; i < librosRentados.size(); i++) {
			resultado = resultado
					|| (librosRentados.get(i).getCopy().getBook().getIsbn()
							.equals(book.getIsbn()));
		}

		return resultado;
	}

	public void refunLoan(final LoanBook loanBook) {
		this.getLoans().remove(loanBook);
	}

	// ---accessors---

	public UserRole getRole() {
		return this.role;
	}

	public void setRole(final UserRole role) {
		this.role = role;
	}

	public String getEmail() {
		return this.email;
	}

	public String getName() {
		return this.name;
	}

	public String getPassword() {
		return this.password;
	}

	public void setEmail(final String newEmail) {
		new EmailValidator().apply(newEmail);
		this.email = newEmail;
	}

	public void setName(final String newName) {
		this.name = newName;
	}

	public void setPassword(final String newPassword) {
		// new PasswordValidatorRule().apply(newPassword);
		this.password = newPassword;
	}

	public Set<LoanBook> getLoans() {
		return this.loans;
	}

	public void setLoans(final Set<LoanBook> loans) {
		this.loans = loans;
	}

	@Override
	public String toString() {
		return this.name;
	}

}
